package com.zenithmind.disk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.disk.mapper.FilesMapper;
import com.zenithmind.disk.mapper.RecycleBinMapper;
import com.zenithmind.disk.pojo.domain.Files;
import com.zenithmind.disk.pojo.domain.RecycleBin;
import com.zenithmind.disk.pojo.query.FileQuery;
import com.zenithmind.disk.pojo.vo.FileVO;
import com.zenithmind.disk.service.FileManagementService;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.annotation.DataCache;
import com.zenithmind.common.annotation.DataCacheEvict;
import com.zenithmind.common.constant.CacheConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件管理服务实现
 * 遵循单一职责原则：专注于文件管理功能
 * 遵循依赖倒置原则：依赖抽象接口
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileManagementServiceImpl implements FileManagementService {

    private final FilesMapper filesMapper;
    private final RecycleBinMapper recycleBinMapper;

    private static final String CACHE_FILES_PREFIX = "files";
    private static final String CACHE_USER_FILES_PREFIX = "user:files";

    @Override
    @Transactional
    @DataCacheEvict(prefix = CACHE_FILES_PREFIX, key = "#fileId")
    public boolean deleteFile(String fileId, String userId) {
        Files file = filesMapper.selectById(fileId);
        if (file == null) {
            log.warn("Attempted to delete non-existent file: fileId={}, userId={}", fileId, userId);
            return false;
        }

        if (!file.getUserId().equals(userId)) {
            log.warn("User {} attempted to delete file {} owned by {}", userId, fileId, file.getUserId());
            throw new RuntimeException("无权限删除该文件");
        }

        // 将文件移入回收站
        RecycleBin recycleBin = new RecycleBin();
        recycleBin.setUserId(userId);
        recycleBin.setFileId(fileId);
        recycleBin.setOriginalPath(file.getParentId());
        recycleBin.setDeleteTime(LocalDateTime.now());
        recycleBin.setExpireTime(LocalDateTime.now().plusDays(30)); // 30天后自动删除

        recycleBinMapper.insert(recycleBin);

        // 更新文件状态为已删除
        file.setStatus(0);
        filesMapper.updateById(file);

        log.info("File moved to recycle bin: fileId={}, userId={}", fileId, userId);
        return true;
    }

    @Override
    @DataCache(prefix = CACHE_FILES_PREFIX, key = "#fileId")
    public FileVO getFileInfo(String fileId) {
        Files files = filesMapper.selectById(fileId);
        if (files == null) {
            throw new RuntimeException("文件不存在");
        }

        FileVO fileVO = new FileVO();
        BeanUtils.copyProperties(files, fileVO);
        
        // 显式设置isDirectory属性，防止类型不匹配问题
        if (files.getIsDirectory() != null) {
            fileVO.setIsDirectory(files.getIsDirectory() == 1);
        } else {
            fileVO.setIsDirectory(false);
        }
        
        return fileVO;
    }

    @Override
    @DataCache(prefix = CACHE_USER_FILES_PREFIX,
               key = "#fileQuery.userId + ':' + #fileQuery.parentId + ':page' + #fileQuery.current",
               expireTime = CacheConstants.TTL_SECONDS_DEFAULT)
    public PageResult<FileVO> filePage(FileQuery fileQuery) {
        Page<Files> page = fileQuery.toPage();

        Page<Files> filesPage = filesMapper.selectPage(page,
            buildQueryWrapper(fileQuery));

        // 转换为VO对象
        List<FileVO> fileVOList = filesPage.getRecords().stream().map(file -> {
            FileVO fileVO = new FileVO();
            BeanUtils.copyProperties(file, fileVO);
            
            if (file.getIsDirectory() != null) {
                fileVO.setIsDirectory(file.getIsDirectory() == 1);
            } else {
                fileVO.setIsDirectory(false);
            }
            
            return fileVO;
        }).collect(Collectors.toList());

        return new PageResult<>(fileVOList, filesPage.getTotal(), 
                               filesPage.getCurrent(), filesPage.getSize());
    }

    @Override
    @Transactional
    @DataCacheEvict(prefix = CACHE_FILES_PREFIX, key = "'*'")
    public boolean deleteBatchFiles(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }

        // 查询要删除的文件
        List<Files> files = filesMapper.selectBatchIds(ids);
        if (files.isEmpty()) {
            return true;
        }

        // 批量移入回收站
        List<RecycleBin> recycleBins = files.stream().map(file -> {
            RecycleBin recycleBin = new RecycleBin();
            recycleBin.setUserId(file.getUserId());
            recycleBin.setFileId(file.getId());
            recycleBin.setOriginalPath(file.getParentId());
            recycleBin.setDeleteTime(LocalDateTime.now());
            recycleBin.setExpireTime(LocalDateTime.now().plusDays(30));
            return recycleBin;
        }).collect(Collectors.toList());

        // 批量插入回收站记录
        recycleBins.forEach(recycleBinMapper::insert);

        // 批量更新文件状态
        files.forEach(file -> {
            file.setStatus(0);
            filesMapper.updateById(file);
        });

        log.info("Batch deleted {} files to recycle bin", files.size());
        return true;
    }

    /**
     * 构建查询条件
     * @param fileQuery 查询参数
     * @return 查询条件
     */
    private LambdaQueryWrapper<Files> buildQueryWrapper(FileQuery fileQuery) {
        LambdaQueryWrapper<Files> queryWrapper = new LambdaQueryWrapper<>();

        // 用户ID条件
        if (StringUtils.isNotBlank(fileQuery.getUserId())) {
            queryWrapper.eq(Files::getUserId, fileQuery.getUserId());
        }

        // 父目录ID条件
        if (StringUtils.isNotBlank(fileQuery.getParentId())) {
            if ("root".equals(fileQuery.getParentId())) {
                queryWrapper.isNull(Files::getParentId);
            } else {
                queryWrapper.eq(Files::getParentId, fileQuery.getParentId());
            }
        }

        // 文件名模糊查询
        if (StringUtils.isNotBlank(fileQuery.getFileName())) {
            queryWrapper.like(Files::getFileName, fileQuery.getFileName());
        }

        // 文件类型条件
        if (StringUtils.isNotBlank(fileQuery.getFileType())) {
            queryWrapper.like(Files::getFileType, fileQuery.getFileType());
        }

        // 是否目录条件
        if (fileQuery.getIsDirectory() != null) {
            queryWrapper.eq(Files::getIsDirectory, fileQuery.getIsDirectory());
        }

        // 状态条件
        if (fileQuery.getStatus() != null) {
            queryWrapper.eq(Files::getStatus, fileQuery.getStatus());
        } else {
            // 默认查询正常状态的文件
            queryWrapper.eq(Files::getStatus, 1);
        }

        // 文件大小范围
        if (fileQuery.getMinFileSize() != null) {
            queryWrapper.ge(Files::getFileSize, fileQuery.getMinFileSize());
        }
        if (fileQuery.getMaxFileSize() != null) {
            queryWrapper.le(Files::getFileSize, fileQuery.getMaxFileSize());
        }

        // 创建时间范围
        if (fileQuery.getCreateTimeStart() != null) {
            queryWrapper.ge(Files::getCreateTime, fileQuery.getCreateTimeStart());
        }
        if (fileQuery.getCreateTimeEnd() != null) {
            queryWrapper.le(Files::getCreateTime, fileQuery.getCreateTimeEnd());
        }

        // 更新时间范围
        if (fileQuery.getUpdateTimeStart() != null) {
            queryWrapper.ge(Files::getUpdateTime, fileQuery.getUpdateTimeStart());
        }
        if (fileQuery.getUpdateTimeEnd() != null) {
            queryWrapper.le(Files::getUpdateTime, fileQuery.getUpdateTimeEnd());
        }

        // 排序
        if (StringUtils.isNotBlank(fileQuery.getSortField())) {
            boolean isAsc = fileQuery.isSortAscending();
            switch (fileQuery.getSortField()) {
                case "fileName":
                    queryWrapper.orderBy(true, isAsc, Files::getFileName);
                    break;
                case "fileSize":
                    queryWrapper.orderBy(true, isAsc, Files::getFileSize);
                    break;
                case "createTime":
                    queryWrapper.orderBy(true, isAsc, Files::getCreateTime);
                    break;
                case "updateTime":
                    queryWrapper.orderBy(true, isAsc, Files::getUpdateTime);
                    break;
                default:
                    queryWrapper.orderByDesc(Files::getCreateTime);
            }
        } else {
            // 默认按创建时间降序
            queryWrapper.orderByDesc(Files::getCreateTime);
        }

        return queryWrapper;
    }

    @Override
    @Transactional
    @DataCacheEvict(prefix = CACHE_FILES_PREFIX, key = "#file.id")
    public FileVO addOrUpdateFileByAdmin(Files file) {
        if (StringUtils.isNotBlank(file.getId())) {
            // 修改操作
            Files existingFile = filesMapper.selectById(file.getId());
            if (existingFile == null) {
                throw new RuntimeException("文件不存在");
            }
            
            // 保持不可修改字段不变
            file.setFilePath(existingFile.getFilePath());
            file.setFileSize(existingFile.getFileSize());
            file.setFileType(existingFile.getFileType());
            file.setFileMd5(existingFile.getFileMd5());
            filesMapper.updateById(file);
        } else {
            // 添加操作仅允许创建文件夹
            if (file.getIsDirectory() != 1) {
                throw new RuntimeException("管理员只能创建文件夹，不能直接创建文件");
            }
            filesMapper.insert(file);
        }

        FileVO fileVO = new FileVO();
        BeanUtils.copyProperties(file, fileVO);
        
        if (file.getIsDirectory() != null) {
            fileVO.setIsDirectory(file.getIsDirectory() == 1);
        } else {
            fileVO.setIsDirectory(false);
        }
        
        return fileVO;
    }
}
